package linkedlist;

/**
 * leetcode 203 移除链表元素
 *
 * 删除链表中等于给定值 val 的所有节点
 *
 * 输入: 1->2->6->3->4->5->6, val = 6
 * 输出: 1->2->3->4->5
 *
 */
public class Solution {
    public ListNode removeElements(ListNode head, int val) {

        while(head != null && head.val == val){
            ListNode delNode = head;
            head = head.next;
            delNode.next = null;
        }
        if(head == null){
            return null;
        }
        ListNode prev = head;
        while(prev.next != null){
            if(prev.next.val == val){
                ListNode delNode = prev.next;
                prev.next = delNode.next;
                delNode.next = null;
            } else {
                prev = prev.next;
            }
        }
        return  head;
    }

    // 使用虚拟头节点
    public ListNode removeElements2(ListNode head, int val) {

        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;

        ListNode prev = dummyHead;
        while(prev.next != null){
            if(prev.next.val == val){
                ListNode delNode = prev.next;
                prev.next = delNode.next;
                delNode.next = null;
            } else {
                prev = prev.next;
            }
        }
        return  dummyHead.next;
    }

    // 使用递归
    public ListNode removeElements3(ListNode head, int val) {
        if(head == null){
            return null;
        }
        ListNode res = removeElements3(head.next, val);
        if(head.val == val){
            return res;
        }else{
            head.next = res;
            return head;
        }
    }

    // 使用递归2
    public ListNode removeElements4(ListNode head, int val) {
        if(head == null){
            return null;
        }
        head.next = removeElements4(head.next, val);
      /*  if(head.val == val){
            return head.next;
        }else{
            return head;
        }*/
        return  head.val == val ? head.next : head;
    }

    // 使用递归,加上打印来进行调试
    public ListNode removeElements5(ListNode head, int val, int depth) {

        String depthString = generateDepthString(depth);
        System.out.print(depthString);
        System.out.println("Call:remove " + val + " in " + head);
        if(head == null){
            System.out.print(depthString);
            System.out.println("Return:" + head);
            return null;
        }

        ListNode res = removeElements5(head.next, val, depth+1);
        System.out.print(depthString);
        System.out.println("After remove " + val + ": " + res);

        ListNode ret;
        if(head.val == val){
            ret = res;
        }else{
            head.next = res;
            ret = head;
        }
        System.out.print(depthString);
        System.out.println("Return:" + ret);
        return ret;
    }

    private String generateDepthString(int depth){
        StringBuilder res = new StringBuilder();
        for (int i = 0; i < depth; i++) {
            res.append("-->");
        }
        return res.toString();
    }
    public static void main(String[] args) {
        int[] nums = {1, 2, 6, 3, 4, 5, 6};
        ListNode head = new ListNode(nums);
        System.out.println(head);

        ListNode res = new Solution().removeElements5(head, 6, 0);
        System.out.println(res);
    }
}
